package com.augrain.microframework.lock.lock;

import com.augrain.microframework.lock.model.LockInfo;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 抽象锁
 *
 * @author biaoy
 * @since 2021/06/10
 */
public abstract class AbstractLock implements Lock {
    /**
     * 锁对象
     */
    protected final RLock lock;

    /**
     * 锁信息
     */
    protected final LockInfo lockInfo;

    /**
     * redissonClient实例
     */
    protected final RedissonClient redissonClient;

    public AbstractLock(RedissonClient redissonClient, LockInfo info) {
        this.redissonClient = redissonClient;
        this.lockInfo = info;
        this.lock = getLock(lockInfo);
    }

    protected abstract RLock getLock(LockInfo lockInfo);

    @Override
    public boolean acquire() {
        try {
            return this.lock.tryLock(lockInfo.getWaitTime(), lockInfo.getLeaseTime(), TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            return false;
        }
    }

    @Override
    public boolean release() {
        if (this.lock.isHeldByCurrentThread()) {
            try {
                return this.lock.forceUnlockAsync().get();
            } catch (InterruptedException | ExecutionException e) {
                return false;
            }
        }
        return false;
    }
}
